#pragma once

#ifndef _CORE_SAFE_MUTEX_H_
#define _CORE_SAFE_MUTEX_H_

#include "Poco/Mutex.h"
#include "Poco/ScopedLock.h"

namespace
{
    typedef Poco::Mutex CSafeMutex;
    typedef Poco::ScopedLock<Poco::Mutex> CSafeScopedLock;

    // poco mutex uses windows' CriticalSection
    // which is already safe...
#if 0
    class CSafeMutex
    {
    public:
        CSafeMutex(void)
            : m_flagLocked(false)
        {
        }

        void lock(void)
        {
            m_lock.lock();
            m_flagLocked = true;
        }

        void unlock(void)
        {
            m_lock.unlock();
            m_flagLocked = false;
        }

        bool IsLocked(void) const
        {
            return m_flagLocked;
        }

        bool tryLock(void)
        {
            return m_lock.tryLock();
        }

        void SetLockFlag(void)
        {
            m_flagLocked = true;
        }

    protected:
        Poco::Mutex m_lock;
        bool m_flagLocked;
    };

    class CSafeScopedLock
    {
    public:
        CSafeScopedLock(CSafeMutex &lock) 
            : m_lock(lock)
            , m_flagAlreadyLocked(false)
        {
            if (!m_lock.tryLock())
            {
                m_lock.lock();
                return;
            }

            if (m_lock.IsLocked())
                m_flagAlreadyLocked = true;
            else
                m_lock.SetLockFlag();
        }

        ~CSafeScopedLock(void)
        {
            if (!m_flagAlreadyLocked)
                m_lock.unlock();
        }

    protected:
        CSafeMutex &m_lock;
        bool m_flagAlreadyLocked;
    };
#endif
}

#endif